package httpsrv

import (
	"context"
	"encoding/json"
	"fmt"
	"judge-service/configs"
	"judge-service/influx"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

// 接收的聚合请求
type aggReq struct {
	AggType    string            `json:"aggType"`
	Metric     string            `json:"metric"`
	Dimensions map[string]string `json:"dimensions"`
	Interval   string            `json:"interval"`
}

// 返回的聚合响应
type aggRsp struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg,omitempty"`
	Data interface{} `json:"data,omitempty"`
}

// AggregateServe 聚合函数的http服务
func AggregateServe() {
	http.HandleFunc("/aggregate", aggregateHandle)

	srv := http.Server{
		Addr:    fmt.Sprintf(":%d", configs.GetConfig().HttpPort),
		Handler: http.DefaultServeMux,
	}

	// 启动http服务
	go func() {
		log.Printf("start http server: %s", srv.Addr)
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %v", err)
		}
	}()

	// 监听信号，优雅关停
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
	sig := <-quit
	log.Printf("signal: %s, shutdown server...", sig)
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatalf("server shutdown: %v", err)
	}
	log.Println("server exiting")
}

func aggregateHandle(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	reqBody := &aggReq{}

	if err := json.NewDecoder(r.Body).Decode(reqBody); err != nil {
		_ = json.NewEncoder(w).Encode(aggRsp{Code: 1, Msg: "json decode error"})
		return
	}

	reqBody.AggType = strings.ToLower(reqBody.AggType) // 忽略大小写，一律转小写

	aggregateRes, err := influx.Aggregate(reqBody.AggType, reqBody.Metric, reqBody.Dimensions, reqBody.Interval)
	if err != nil {
		_ = json.NewEncoder(w).Encode(aggRsp{Code: 2, Msg: err.Error()})
		return
	}
	_ = json.NewEncoder(w).Encode(aggRsp{Code: 0, Msg: "success", Data: aggregateRes})
}
